using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace Lu62Viewer
{
    public partial class MyLu62Viewer : UserControl
    {
        #region Private Vars
        private char m_selectedSeparator = '#';
        private char m_selectedTerminator = '$';
        private int m_selectedSegmentNameLenght = 6;
        private const string rootNodeText = "root";
        private const string emptyString = "empty";
        private delegate void AppendNumberDelegate(Decimal number);
        #endregion        

        #region Constructor and initialization
        public MyLu62Viewer()
        {
            InitializeComponent();
            initialize();
        }

        private void initialize()
        {
            cbSeparatore.SelectedIndex = 0;
            cbTerminatore.SelectedIndex = 0;
            cbNomiSegmentiLenght.SelectedIndex = 0;
            Label afterLabel = new Label();
            afterLabel.Text = "Segmenti trovati ";
            afterLabel.AutoSize = true;

            txtRawLuText.EnableAutoDragDrop = true;
            this.txtRawLuText.DragEnter += new DragEventHandler(txtRawLuText_DragEnter);
            this.txtRawLuText.DragDrop += new DragEventHandler(txtRawLuText_DragDrop); 
        }
        #endregion                

        #region UI operations misc
        private void goToCharPosition()
        {            
            GoToCharPosition myFormPosition = new GoToCharPosition();
            if (myFormPosition.ShowDialog() == DialogResult.OK)
            {
                int i = 0;
                foreach (char _c in txtRawLuText.Text)
                {
                    if (i == myFormPosition.CharPosition - 1)
                    {
                        txtRawLuText.Select(i, 1);
                        return;
                    }
                    i++;
                }
                txtRawLuText.Select(txtRawLuText.Text.Length - 1, 1);
            }            
        }        

        private void cut()
        {
            if (txtRawLuText.SelectedText.Length == 0)
                return;
            Clipboard.SetText(txtRawLuText.SelectedText);
            txtRawLuText.SelectedText = string.Empty;
        }

        private void copy()
        {
            if (txtRawLuText.SelectedText.Length == 0)
                return;
            Clipboard.SetText(txtRawLuText.SelectedText);
        }

        #endregion

        #region Click events
        private void cbTerminatore_SelectedIndexChanged(object sender, EventArgs e)
        {
            m_selectedTerminator = cbTerminatore.Text.ToCharArray()[0];
        }

        private void cbNomiSegmentiLenght_SelectedIndexChanged(object sender, EventArgs e)
        {
            m_selectedSegmentNameLenght = Convert.ToInt32(cbNomiSegmentiLenght.Text);
        }

        private void cbSeparatore_SelectedIndexChanged(object sender, EventArgs e)
        {
            m_selectedSeparator = cbSeparatore.Text.ToCharArray()[0];
        }

        private void tsbOpenFile_Click(object sender, EventArgs e)
        {
            try
            {
                openFileDialog1.Filter = "Txt Files|*.txt|All files|*.*";
                DialogResult res = openFileDialog1.ShowDialog(this);
                if (res == DialogResult.OK)
                {
                    txtRawLuText.Text = UIOperations.OpenFile(openFileDialog1.FileName);
                }
                tvLuTree.Nodes.Clear();
                txtRawLuText.ForeColor = Color.Black;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnFillTree_Click(object sender, EventArgs e)
        {
            try
            {
                int nodeCount = UIOperations.FillTree(tvLuTree, txtRawLuText.Text, m_selectedTerminator, m_selectedSeparator, m_selectedSegmentNameLenght);
                tssNodeCount.Text = string.Format("Operation completed. Found {0} segments", nodeCount.ToString());
            }
            catch (ArgumentOutOfRangeException exAOR)
            {
                MessageBox.Show(string.Format("Check the segment length inserted [Error message: {0}]", exAOR.Message), "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);//Verifica il numero di caratteri impostato per il nome dei segmenti [Error message: {0}]", exAOR.Message), "Attenzione", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Application error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void tsmGoToPosition_Click(object sender, EventArgs e)
        {
            try
            {
                goToCharPosition();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void tsmCut_Click(object sender, EventArgs e)
        {
            cut();
        }

        private void tsmCopy_Click(object sender, EventArgs e)
        {
            copy();
        }

        private void tsmPaste_Click(object sender, EventArgs e)
        {
            txtRawLuText.Paste();
        }

        private void tsmClearText_Click(object sender, EventArgs e)
        {
            txtRawLuText.Text = string.Empty;
        }

        private void tsmSelectAll_Click(object sender, EventArgs e)
        {
            txtRawLuText.SelectAll();
        }
        #endregion

        #region Treevie operations
        private void tvLuTree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            try
            {
                string nomeSegmentoInteressato = string.Empty;
                string indexDesc = string.Empty;
                string descSegmentoSelezionato = string.Empty;
                int totNodiSegmentoSelezionato = -1;
                if (e.Node.Text != rootNodeText)
                {
                    int indiceSelezionato = -1;
                    if (e.Node.Nodes.Count > 0)
                    {
                        totNodiSegmentoSelezionato = e.Node.Nodes.Count;
                        indiceSelezionato = 1;
                        nomeSegmentoInteressato = e.Node.Text;
                    }
                    else if (e.Node.Parent != null)
                    {
                        indiceSelezionato = e.Node.Parent.Nodes.IndexOf(e.Node) + 2;
                        totNodiSegmentoSelezionato = e.Node.Parent.Nodes.Count;
                        nomeSegmentoInteressato = e.Node.Parent.Text;
                    }
                    indexDesc = string.Format("[{0}/{1}]", indiceSelezionato, totNodiSegmentoSelezionato + 1);
                }                
                tssNodeCount.Text = string.Format("Segment {0}: {1} fields found  {2}", nomeSegmentoInteressato, totNodiSegmentoSelezionato + 1, indexDesc);

                changeColor((MyNode)e.Node);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void changeColor(MyNode _nodoSelezionato)
        {
            txtRawLuText.SelectAll();
            txtRawLuText.SelectionColor = Color.Black;

            Type t = _nodoSelezionato.GetType();
            if (t.Name == "MySegmentNode")
            {
                MySegmentNode segmentoSelezionato = (MySegmentNode)_nodoSelezionato;
                txtRawLuText.Select(segmentoSelezionato.Pos, segmentoSelezionato.Lenght);
                txtRawLuText.SelectionColor = Color.Red;
                txtRawLuText.ScrollToCaret();
            }
            else if (t.Name == "MyFieldNode")
            {
                MySegmentNode segmentoSelezionato = (MySegmentNode)_nodoSelezionato.Parent;
                txtRawLuText.Select(segmentoSelezionato.Pos, segmentoSelezionato.Lenght);
                txtRawLuText.SelectionColor = Color.Red;

                MyFieldNode campoSelezionato = (MyFieldNode)_nodoSelezionato;
                txtRawLuText.Select((segmentoSelezionato.Pos + campoSelezionato.Pos) - campoSelezionato.Lenght, campoSelezionato.Lenght);
                txtRawLuText.SelectionColor = Color.Green;

                txtRawLuText.ScrollToCaret();
            }
        }
        #endregion

        #region DragDrop operations
        private void txtRawLuText_DragDrop(object sender, DragEventArgs e)
        {
            try
            {
                if (e.Data.GetDataPresent(typeof(string)))
                {
                    txtRawLuText.Text += (string)e.Data.GetData(typeof(string));
                }
                if (e.Data.GetDataPresent(System.Windows.Forms.DataFormats.FileDrop))
                {
                    string[] fileArray = (string[])e.Data.GetData(DataFormats.FileDrop);
                    for (int i = 0; i < fileArray.Length; i++)
                    {
                        string filePath = fileArray[i];
                        using (StreamReader reader = new StreamReader(filePath, System.Text.Encoding.UTF8))
                        {
                            txtRawLuText.Text = reader.ReadToEnd();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void txtRawLuText_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(string)) || e.Data.GetDataPresent(System.Windows.Forms.DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
            }
        }
        #endregion                 

        public MySegmentNode MySelectedSegmentNode
        {
            get 
            {
                TreeNode n = tvLuTree.SelectedNode;
                if (n != null)
                {
                    Type t = n.GetType();
                    if (t.Name == "MySegmentNode")
                        return tvLuTree.SelectedNode as MySegmentNode;
                }
                return null;
            }
        }

        private void copyLabelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                Clipboard.SetText(tvLuTree.SelectedNode.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }        
    }
}